package com.zysc.processflow.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zysc.processflow.common.base.ResultBody;
import com.zysc.processflow.entity.Attachment;
import com.zysc.processflow.service.IAttachmentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import com.zysc.processflow.common.base.BaseController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;

/**
 * <p>
 * 附件表 前端控制器
 * </p>
 *
 * @author 正元智慧城市_
 * @since 2022-11-18
 */
@Api(value = "附件表 ", tags = "附件表 ")
@RestController
@RequestMapping("/attachment")
public class AttachmentController extends BaseController<Attachment> {

    @Autowired
    IAttachmentService service;

    @Value("${fileUrl}")
    private String fileUrl;

    public AttachmentController(IAttachmentService service) {
        super(service);
    }

    /**
     * 文件下载
     * /download/日期文件夹/文件名
     */
    @ApiOperation("附件下载")
    @GetMapping("/download/{path}/{filename:.+}")
    @ResponseBody
    public ResponseEntity<Resource> downloadFile(@PathVariable String path, @PathVariable String filename, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String reltiveUrl = path + "/" + filename;
        Resource file = service.loadAsResource(reltiveUrl);
        if (file != null)
            return ResponseEntity
                    .ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .body(file);
        else
            return null;
    }
    /**
     * 图片/pdf实现预览,其他文件实现下载
     * /preview/日期文件夹/文件名
     */
    @ApiOperation("附件下载或者预览")
    @GetMapping("/preview/{path}/{filename:.+}")
    @ResponseBody
    public ResponseEntity<Resource> previewFile(@PathVariable String path, @PathVariable String filename, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String reltiveUrl = path + "/" + filename;
        Resource file = service.loadAsResource(reltiveUrl);
        String contentType = "application/octet-stream";
        String disposition = "attachment; filename=\"" + file.getFilename() + "\"";
        int index = filename.lastIndexOf(".");
        if (index == -1) {
            return null;
        }
        String extensionName = filename.substring(index + 1);
        Map<String,String> map = new HashMap<String,String>();
        map.put("pdf","application/pdf");
        map.put("png","image/png");
        map.put("jpg","image/jpg");
        map.put("jpeg","image/jpeg");
        map.put("gif","image/gif");
        if(map.containsKey(extensionName.toLowerCase())){
            disposition="inline";
            contentType=map.get(extensionName.toLowerCase());
        }
        if (file != null)
            return ResponseEntity
                    .ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, disposition)
                    .contentType(MediaType.parseMediaType(contentType))
                    .body(file);
        else
            return null;
    }

    @ApiOperation("APP安装文件下载")
    @GetMapping("/downloadApp")
    @ResponseBody
    public ResponseEntity<Resource>  downloadApp(HttpServletRequest request, HttpServletResponse response)throws Exception {

        Resource file = service.loadAsResource(fileUrl);
        if (file != null)
            return ResponseEntity
                    .ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .body(file);
        else
            return null;

//            File file=new File(fileUrl);
//            String filename=file.getName();
//            // 以流的形式下载文件。
//            InputStream fis = new BufferedInputStream(new FileInputStream(fileUrl));
//            byte[] buffer = new byte[fis.available()];
//            fis.read(buffer);
//            fis.close();
//            // 清空response
//            response.reset();
//
//            response.setContentType("application/octet-stream;charset=UTF-8");
//            String fileName = new String(filename.getBytes("gb2312"), "iso8859-1");
//            response.setHeader("Content-disposition", "attachment;filename=" + fileName);
//            OutputStream ouputStream = response.getOutputStream();
//            ouputStream.write(buffer);
//            ouputStream.flush();
//            ouputStream.close();

    }
    /**
     * 批量上传。
     */
    @ApiOperation("批量上传附件")
    @PostMapping(value = "/batchupload")
    public ResultBody uploadBatchFiles(@RequestParam("files") List<MultipartFile> files, @RequestParam(value = "linkid", required = false) Long linkid, @RequestParam(value = "type", required = false) String type) {
        if (files == null)
            return ResultBody.error("接收参数不可为空", 500);
        List<Attachment> fis = new ArrayList<>();
        for (Integer i = 0; i < files.size(); i++) {
            try {
                Long fileid = (long) (System.currentTimeMillis()*Math.random());
                MultipartFile file = files.get(i);
                String filepath = service.store(file, fileid);
                Attachment fi = new Attachment();
                fi.setFilename(file.getOriginalFilename());
                fi.setPath(filepath);
                fi.setId(fileid);
                fi.setMime(file.getContentType());
                fi.setSize(file.getSize());
                fi.setLinkid(linkid);
                fi.setType(type);
                fi.setCreatetime(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
                fis.add(fi);

                ;
            } catch (Exception ex) {
                return ResultBody.error(ex.getMessage(), 500);
            }
        }
        Boolean rs = service.saveBatch(fis);
        if (rs) {
            return ResultBody.Success(fis, "上传成功");
        } else {
            return ResultBody.Success(fis, "保存文件失败");
        }
    }


    @ApiOperation("上传单一附件")
    @PostMapping("/upload")
    public ResultBody uploadFile(@RequestParam("file") MultipartFile file, @RequestParam(value = "linkid", required = false) Long linkid, @RequestParam(value = "type", required = false) String type) {
        try {
            Long fileid = (long) (System.currentTimeMillis()*Math.random());
            String filepath = service.store(file, fileid);
            Attachment fi = new Attachment();
            fi.setFilename(file.getOriginalFilename());
            fi.setPath(filepath);
            fi.setId(fileid);
            fi.setMime(file.getContentType());
            fi.setSize(file.getSize());
            fi.setLinkid(linkid);
            fi.setType(type);
            fi.setCreatetime(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
            Boolean rs = service.save(fi);
            if (rs) {
                return ResultBody.Success(fi, "上传成功");
            } else {
                return ResultBody.Success(fi, "保存文件失败");
            }
        } catch (Exception ex) {
            String msg = ex.getMessage();
            return ResultBody.error(msg, 500);
        }
    }


    @ApiOperation("根据file id数组删除附件")
    @PostMapping("/deletefiles")
    public ResultBody delfiles(@RequestParam(value = "fileids", required = false) String... fileids) {
        if (fileids == null)
            return ResultBody.error("未接受到参数", 500);
        List<String> p = Arrays.asList(fileids);
        List<Attachment> list = service.listByIds(p);
        List<String> filepath = new ArrayList<>();
        list.forEach(item -> filepath.add(item.getPath()));
        service.deletefiles(filepath);
        Boolean rs = service.removeByIds(p);
        if (rs) {
            return ResultBody.Success(true, "删除成功");
        } else {
            return ResultBody.Success(false, "删除失败");
        }
    }

    @ApiOperation("根据file id数组查询附件")
    @PostMapping("/getFiles")
    public ResultBody getFiles(@RequestParam(value = "fileids", required = false) String... fileids) {
        Map resultmap = new HashMap();
        List<Attachment> list = new ArrayList<>();
        List<String> p = Arrays.asList(fileids);
        if (p.size() != 0) {
            list = service.listByIds(p);
        }
        List<String> filepath = new ArrayList<>();
        list.forEach(item -> filepath.add(item.getPath()));
        resultmap.put("file", list);
        resultmap.put("filepath", filepath);
        return ResultBody.Success(resultmap);
    }

    /**
     * 根据条件查询附件信息。
     *
     * @param params
     * @return
     */
    @ApiOperation("根据条件查询附件信息")
    @PostMapping("/GetFilesByCon")
    public ResultBody GetFilesByCon(@RequestBody Map<String, Object> params) {
//        Integer pageIndex = (Integer) params.get("pageIndex");
//        Integer pageSize = (Integer) params.get("pageSize");
        String[] fileids = params.get("fileids") != null ? (String[]) params.get("fileids") : null;
        String fileid = (String) params.get("fileid");
        String classify = (String) params.get("classify");
        String linkid = (String) params.get("linkid");
        QueryWrapper<Attachment> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(fileid != null&&fileid !="", Attachment::getId, fileid)
                .eq(linkid != null&&linkid != "", Attachment::getLinkid, linkid)
                .eq(classify != null&&classify !="", Attachment::getType, classify)
                .in(fileids != null && fileid.length() > 0, Attachment::getId, fileids);
        List<Attachment> list = service.list(queryWrapper);
        return ResultBody.Success(list);
    }

    @ApiOperation("修改附件表信息")
    @PostMapping("UpdateAttachment")
    public ResultBody UpdateAttachment(@RequestBody Attachment entity){
        if(entity!=null&&entity.getId()!=null){
            return ResultBody.Success(service.updateById(entity));
        }
        return ResultBody.Success(false,"参数不能为空");
    }
}
